package com.jblog.common.web.freemarker;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.jblog.common.util.MonthUtil;
import com.jblog.common.util.MonthUtil.Format;
import com.jblog.common.web.freemarker.exception.MustNotNullException;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
 * Chnage month to num, or num to month
 * <p>
 * for example:<br>
 * <code>
 * january -> 1, august -> 8
 * <br>
 * 1 -> january, 8 -> august
 * </code>
 */
public class MonthDirective implements TemplateDirectiveModel {

    /**
     * if num and month at the same time, num first 
     */
    public static final String PARAM_NUM   = "num";
    public static final String PARAM_MONTH = "month";
    public static final String PARAM_FORMAT  = "format";
    
    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void execute(Environment env, Map params, TemplateModel[] loopVars,
            TemplateDirectiveBody body) throws TemplateException, IOException {
        Integer num = DirectiveUtils.getInt(PARAM_NUM, params);
        String month = DirectiveUtils.getString(PARAM_MONTH, params);
        String sformat = DirectiveUtils.getString(PARAM_FORMAT, params).toUpperCase();
        
        if (null == num && null == month) {
            throw new MustNotNullException(PARAM_NUM + "," + PARAM_MONTH);
        } else {
            Writer out = env.getOut();
            if (null != num) {
                Format format = null;
                if (StringUtils.isNotBlank(sformat)) {
                    if (Format.LONG.toString().equals(sformat) || Format.SHORT.toString().equals(sformat)) {
                        format = Format.valueOf(sformat);
                    } else {
                        throw new RuntimeException("parameter format must be \"long\" or \"short\"");
                    }
                }
                out.append(MonthUtil.num2Month(num, format));
            } else {
                out.append(MonthUtil.Month2Num(month).toString());
            }
        }
    }

}
